package tool.zyk.protocol;

import com.alibaba.fastjson2.JSON;
import io.netty.buffer.ByteBuf;
import io.netty.buffer.ByteBufAllocator;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.ByteToMessageCodec;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import java.io.ByteArrayOutputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.nio.charset.Charset;
import java.util.List;

/**
 * author: zyk
 * datetime: 2024/1/27 11:12
 * describe:
 */
@Slf4j
public class ProtocolDIY {

    private static final byte[] magicNo = new byte[]{0, 1, 2, 3};

    private static final byte version_no = 1;

    private static final byte serializable_type = 1;

    public static void main(String[] args) throws Exception {

        MyProtocol myProtocol = new MyProtocol();
        EmbeddedChannel channel = new EmbeddedChannel(myProtocol);
        Message wuhu = new Message(new UserInfo("age","zhangyongkang"), 132132);

        ByteBuf buffer = ByteBufAllocator.DEFAULT.buffer();
        new MyProtocol().encode(null,wuhu,buffer);

        channel.writeInbound(buffer);

    }

    public static class MyProtocol extends ByteToMessageCodec<Message> {
        //魔术  判定是否为有效的数据包
        // 版本号
        //序列化算法
        //指令类型
        //请求序号  增加全双工能力
        // 正文长度
        //消息内容

        @Override
        protected void encode(ChannelHandlerContext ctx, Message msg, ByteBuf out) throws Exception {
            //魔术
            out.writeBytes(magicNo);
            //版本号
            out.writeByte(version_no);
            //序列化算法
            out.writeByte(serializable_type);
            //指令类型？ 登录？？
            out.writeByte(1);
            //请求序号
            out.writeInt(msg.getSequenceId());
            ByteArrayOutputStream byt = new ByteArrayOutputStream();
            ObjectOutputStream oss = new ObjectOutputStream(byt);
            String resultJSONString = JSON.toJSONString(msg.getMessageBody());
            oss.writeObject(resultJSONString);
            log.info("send string:{}",resultJSONString);
            byte[] resultByteArray = byt.toByteArray();
            //4个字节  数据的长度
            out.writeInt(resultByteArray.length);
            //最终数据
            out.writeBytes(resultByteArray);
        }

        @Override
        protected void decode(ChannelHandlerContext ctx, ByteBuf in, List<Object> out) throws Exception {
            //魔法值
            ByteBuf byteBuf = in.readBytes(magicNo.length);
            log.info("magic num:{}", byteBuf.readBytes(4).toString(Charset.defaultCharset()));
            //版本号
            byte versionNo = in.readByte();
            log.info("versionNo:{}", versionNo);
            //序列化算法
            byte serializable_type = in.readByte();
            log.info("serializable type:{}", serializable_type);
            //指令类型
            byte order_type = in.readByte();
            log.info("order_type:{}", order_type);
            //请求序号
            int requestId = in.readInt();
            log.info("request_id:{}", requestId);
            //数据长度
            int dataLength = in.readInt();
            log.info("datalength:{}", dataLength);
            //数据
            ByteBuf byteBuf1 = in.readBytes(dataLength);
            String resultString = byteBuf1.toString(Charset.defaultCharset());
            System.out.println(resultString);
            log.info("result:{}", resultString);


        }
    }

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public static class Message {
        private Object messageBody;
        private Integer sequenceId;
    }
}
